<script setup>
import {computed,reactive,ref,onMounted,onUpdated} from 'vue'
import MarkdownIt  from 'markdown-it'
import hljs from 'highlight.js'
import 'highlight.js/styles/androidstudio.css'
const props = defineProps({
  content:{
    type:String,
    required:true,
  },
  showCursor:{
    type:Boolean,
    default:false
  }
})
const md = new MarkdownIt({
  highlight: function (code, lang) {
    if(lang && hljs.getLanguage(lang)){
      return hljs.highlight(code,{language:lang}).value
    }
    return hljs.highlightAuto(code).value
  }
});

const markdownContent = computed(()=>{
  return md.render(props.content)
})

const pos = reactive({x:0,y:0})
const contentRef = ref(null)


function getLastTextNode(dom){
  const children = dom.childNodes
  for(let i = children.length-1; i >= 0;i--){
    const node = children[i];
    if(node.nodeType === Node.TEXT_NODE && /\S/.test(node.nodeValue)){
      node.nodeValue = node.nodeValue.replace(/\s+$/,'')
      return node
    }else if(node.nodeType === Node.ELEMENT_NODE){
      const last = getLastTextNode(node)
      if(last){
        return last
      }
    }
  }
  return null
}

function updateCursor(){
  const contentDom = contentRef.value
  const lastText = getLastTextNode(contentDom)
  const txtNode = document.createTextNode('\u200b')
  if(lastText){
    lastText.parentElement.appendChild(txtNode)
  }else{
    contentDom.appendChild(txtNode)
  }
  const domRect = contentDom.getBoundingClientRect()
  const range = document.createRange()
  range.setStart(txtNode,0)
  range.setEnd(txtNode,0)
  const rect = range.getBoundingClientRect()
  pos.x = rect.left - domRect.left
  pos.y = rect.top - domRect.top
  txtNode.remove()
}

onMounted(updateCursor)
onUpdated(updateCursor)

</script>


<template>
  <div class="container">
    <div class="markdown-body" ref="contentRef" v-html="markdownContent"></div>
    <div v-show="showCursor" class="cursor"></div>
  </div>
</template>


<style lang="scss" scoped>
.container{
  position: relative;
  .cursor{
    content:'';
    position: absolute;
    width: 1em;
    height: 1em;
    border-radius: 50%;
    background: #000;
    animation: toggle .8s infinite;
    opacity: 0;
    transform: translateY(5px);
    left: calc( v-bind('pos.x') * 1px );
    top: calc( v-bind('pos.y') * 1px );
  }
  :deep(.markdown-body){
    user-select: text;
    background: inherit;
    // line-height: 18px;
    line-height: normal;
    font-size: 16px;
    table{
      border-collapse: collapse !important;
      th{
        font-weight: 700;
      }
      th, td {
        padding: 4px;
        border: 1px solid black !important;
      }
    }
    ol,ul,li{
      margin-left: 20px;
    }
    ol{
      li{
        list-style:decimal;
      }
    }
    ul{
      li{
        list-style:circle;
      }
    }
    strong{
      font-weight: 700;
    }
    pre{
      padding: 10px;
      // background: #f0f0f0;
    }
    code{
      white-space: break-spaces;
    }
  }
}
@keyframes toggle {
  30%{
    opacity: 1;
  }
}
</style>